using System;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.ExpressApp.DC;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using System.Collections.Generic;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;

namespace DomainComponents.XCRM
{
    public enum SaleStage
    {
        Unknown = 0,
        Lead = 1,
        Opportunity = 2,
        Quote = 3,
        Order = 4,
        Invoice = 5,
        Sale = 6
    }


    [DomainComponent]
    public interface ISaleStageHistory
    {
        [DevExpress.ExpressApp.DC.Aggregated, VisibleInDetailView(false)]
        IList<ILeadHistoryRecord> LeadHistoryRecords { get; }
        ILeadHistoryRecord FindLeadHistoryRecord(SaleStage saleStage);
    }


    [DomainComponent]
    [NonPersistentDc]
    public interface ISaleStageHistoryTarget
    {
        [System.ComponentModel.Browsable(false)]
        SaleStage SaleStage { get; }
        [System.ComponentModel.Browsable(false)]
        ISaleStageHistory History { get; }
    }

    [DomainLogic(typeof(ISaleStageHistoryTarget))]
    public class ISaleStageHistoryTargetLogic
    {
        public static void OnSaving(ISaleStageHistoryTarget saleStageHistoryTarget, IObjectSpace os)
        {
            if (saleStageHistoryTarget.History != null)
            {
                bool addHistoryRecord = true;
                foreach (ILeadHistoryRecord historyRecord in saleStageHistoryTarget.History.LeadHistoryRecords)
                {
                    if (historyRecord.SaleStage == saleStageHistoryTarget.SaleStage)
                        addHistoryRecord = false;
                }
                if (addHistoryRecord)
                {
                    ILeadHistoryRecord historyRecord = os.CreateObject<ILeadHistoryRecord>();
                    historyRecord.SaleStage = saleStageHistoryTarget.SaleStage;
                    saleStageHistoryTarget.History.LeadHistoryRecords.Add(historyRecord);
                }
            }
        }
        private static bool GetLeadFrom(ILeadTarget leadTarget, out ISaleStageHistory result)
        {
            result = null;
            if (leadTarget != null)
            {
                result = leadTarget.SourceLead as ISaleStageHistory;
                return true;
            }
            return false;
        }
        private static bool GetLeadFrom(IOpportunityTarget opportunityTarget, out ISaleStageHistory result)
        {
            result = null;
            if (opportunityTarget != null)
            {
                return GetLeadFrom(opportunityTarget.SourceOpportunity as ILeadTarget, out result);
            }
            return false;
        }
        public static ISaleStageHistory Get_History(ISaleStageHistoryTarget saleStageHistoryTarget)
        {
            ISaleStageHistory result = null;
            if (GetLeadFrom(saleStageHistoryTarget as ILeadTarget, out result))
            {
                return result;
            }
            if (GetLeadFrom(saleStageHistoryTarget as IOpportunityTarget, out result))
            {
                return result;
            }
            return null;
        }
        public static SaleStage Get_SaleStage(ISaleStageHistoryTarget target)
        {
            if (target is IOpportunity)
            {
                return SaleStage.Opportunity;
            }
            else if (target is IQuote)
            {
                return SaleStage.Quote;
            }
            else if (target is IOrder)
            {
                return SaleStage.Order;
            }
            else if (target is IInvoice)
            {
                return ((IInvoice)target).Status == InvoiceStatus.Completed ?
                    SaleStage.Sale : SaleStage.Invoice;
            }
            return SaleStage.Unknown;
        }
    }

    [DomainLogic(typeof(ISaleStageHistory))]
    public class LeadSaleStageHistoryLogic
    {
        public static void AfterConstruction(ISaleStageHistory self, IObjectSpace os)
        {
            ILeadHistoryRecord historyRecord = os.CreateObject<ILeadHistoryRecord>();
            historyRecord.SaleStage = SaleStage.Lead;
            ((ISaleStageHistory)self).LeadHistoryRecords.Add(historyRecord);
        }
        public static ILeadHistoryRecord FindLeadHistoryRecord(ISaleStageHistory history, SaleStage saleStage)
        {
            List<ILeadHistoryRecord> historyRecords = new List<ILeadHistoryRecord>(history.LeadHistoryRecords);
            ILeadHistoryRecord result = null;
            foreach (ILeadHistoryRecord record in historyRecords)
            {
                if (record.SaleStage == saleStage)
                {
                    if (result != null)
                    {
                        throw new InvalidOperationException("Lead history item is duplicated.");
                    }
                    result = record;
                }
            }
            return result;
        }
    }


    [DomainComponent]
    public interface ILeadHistoryRecord
    {
        SaleStage SaleStage { get; set; }
        int StageOrder { get; }
    }

    [DomainLogic(typeof(ILeadHistoryRecord))]
    public class LeadHistoryRecordLogic
    {
        public static int Get_StageOrder(ILeadHistoryRecord record)
        {
            return (int)record.SaleStage;
        }
    }

    //[DefaultClassOptions]
    ////[ImageName("BO_Contact")]
    ////[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
    ////[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
    ////[Persistent("DatabaseTableName")]
    //// Specify more UI options using a declarative approach (http://documentation.devexpress.com/#Xaf/CustomDocument2701).
    //public class ILead_SaleStageHistory : BaseObject
    //{ // Inherit from a different class to provide a custom primary key, concurrency and deletion behavior, etc. (http://documentation.devexpress.com/#Xaf/CustomDocument3146).
    //    public ILead_SaleStageHistory(Session session)
    //        : base(session)
    //    {
    //    }
    //    public override void AfterConstruction()
    //    {
    //        base.AfterConstruction();
    //        // Place your initialization code here (http://documentation.devexpress.com/#Xaf/CustomDocument2834).
    //    }
    //    //private string _PersistentProperty;
    //    //[XafDisplayName("My display name"), ToolTip("My hint message")]
    //    //[ModelDefault("EditMask", "(000)-00"), Index(0), VisibleInListView(false)]
    //    //[Persistent("DatabaseColumnName"), RuleRequiredField(DefaultContexts.Save)]
    //    //public string PersistentProperty {
    //    //    get { return _PersistentProperty; }
    //    //    set { SetPropertyValue("PersistentProperty", ref _PersistentProperty, value); }
    //    //}

    //    //[Action(Caption = "My UI Action", ConfirmationMessage = "Are you sure?", ImageName = "Attention", AutoCommit = true)]
    //    //public void ActionMethod() {
    //    //    // Trigger a custom business logic for the current record in the UI (http://documentation.devexpress.com/#Xaf/CustomDocument2619).
    //    //    this.PersistentProperty = "Paid";
    //    //}
    //}
}
